package com.ruoyi.framework.aspectj;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.SpringContextUtils;
import com.ruoyi.framework.config.DruidConfig;
import com.ruoyi.framework.datasource.DynamicDataSource;
import com.ruoyi.system.domain.SysDataSource;
import com.ruoyi.system.service.ISysDataSourceService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.framework.datasource.DynamicDataSourceContextHolder;

import javax.annotation.Resource;

/**
 * 多数据源处理
 *
 * @author ruoyi
 */
@Aspect
@Order(1)
@Component
public class DataSourceAspect
{


    protected Logger logger = LoggerFactory.getLogger(getClass());


    @Pointcut("@annotation(com.ruoyi.common.annotation.DataSource)"
            + "|| @within(com.ruoyi.common.annotation.DataSource)")
    public void dsPointCut()
    {

    }
//
//    @Before("dsPointCut()")
//    public void doBefore(JoinPoint joinPoint) throws Throwable{
//        logger.info("前置通知，方法执行之前执行！");
//        Signature signature1 = joinPoint.getSignature();
//        logger.info("signature1:{}", signature1);
//        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
//        logger.info("signature:{}", signature);
//        Method method = signature.getMethod();
//        logger.info("method:{}", method);
//        logger.info("方法名称: ",method.getName());
//        DataSource dataSource = method.getAnnotation(DataSource.class);
//        boolean annotationPresent = method.isAnnotationPresent(DataSource.class);
//        logger.info("annotationPresent:{}", annotationPresent);
//
//        DruidConfig dynamicDataSourceConfig = SpringContextUtils.getBean(DruidConfig.class);
//        Map<Object,Object> map = dynamicDataSourceConfig.getTargetDataSources();
//        logger.info("TargetDataSource:"+map.toString());
//
//        String dataSourceType = String.valueOf(dataSource.value());
//        boolean flag;
//        String name = "";
//        switch (dataSourceType) {
//            case "MASTER":
//                flag = true;
//                name = DataSourceType.MASTER.name();
//                break;
//            case "SALVE":
//                flag = true;
//                name = DataSourceType.SLAVE.name();
//                break;
//            case "OTHER":
//                flag = true;
//                name = "OTHER";
//                if (map.get(name) != null){
//                    break;
//                } else {
//                    //获取传入参数
//                    Object[] args = joinPoint.getArgs();
//                    JSONObject json = (JSONObject) args[0];
//                    Long dataSourceId = json.getLong("dataSourceId");
//                    logger.info("获取的数据源ID:"+dataSourceId);
//
//                    //从传入参数获取业务ID 查找数据源信息，设置数据源信息
//                    SysDataSource source = sysDataSourceService.getById(dataSourceId);
//                    String url = source.getUrl();
//                    String userName = source.getUserName();
//                    String userPwd = source.getUserPwd();
//
//                    logger.info("数据源切换"+url);
//
//                    DruidDataSource s = dynamicDataSourceConfig.createDataSource(name, url, userName, userPwd, source.getDriverType());
//                }
//                break;
//            default:
//                flag = false;
//                break;
//        }
//
//        if(!flag){
//            logger.error("**************注意**************");
//            name = DataSourceType.MASTER.name();
//            logger.info("加载到未知数据源，系统自动设置数据源为默认数据源！");
//        }
//
//        DynamicDataSource.setDataSource(name);
//        DynamicDataSourceContextHolder.setDataSourceType(name);
//        logger.info("当前数据源：" + name);
//        logger.info("set datasource is "+ name);
//    }
//
//    @After("dsPointCut()")
//    public void doAfter(){
//        logger.info("*******************准备清除数据源**********************");
//        DynamicDataSource.clearDataSource();
//        DynamicDataSourceContextHolder.clearDataSourceType();
//        logger.info("*******************删除数据源成功**********************");
//    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable
    {
        DataSource dataSource = getDataSource(point);

        if (StringUtils.isNotNull(dataSource))
        {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }

        try
        {
            return point.proceed();
        }
        finally
        {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

    /**
     * 获取需要切换的数据源
     */
    public DataSource getDataSource(ProceedingJoinPoint point)
    {
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
        if (Objects.nonNull(dataSource))
        {
            return dataSource;
        }

        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
    }
}
